/* Filename: cleanup.c
 * No.84.线程-线程终止和栈清理
 * $ ps axm
 * $ ps ax -L
 * Description:
 * $ gcc -Wall cleanup.c -o cleanup -lpthread
 * Last modified: humble 20200411 17:32
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>

//pthread_cleanup_push 和 pthread_cleanup_pop 需要成对使用，位置无所谓
//demo 不为0或1，则编译报错
#define demo (1) //1

static void func_cleanup(void *p)
{
    puts(p);
    return;
}

static void *func(void *p)
{
    puts("pthread func is working");
    pthread_cleanup_push(func_cleanup, "cleanup1");
    pthread_cleanup_push(func_cleanup, "cleanup2");
    pthread_cleanup_push(func_cleanup, "cleanup3");

    puts("push over");

#if (demo == 0)
    pthread_cleanup_pop(1);
    pthread_cleanup_pop(0);
    pthread_cleanup_pop(0);
#endif

    pthread_exit(NULL);

#if (demo == 1)
    //如果 pthread_cleanup_pop 放在pthread_exit后面，传参execute永远为真
    pthread_cleanup_pop(1);
    pthread_cleanup_pop(0);
    pthread_cleanup_pop(0);
#endif
}

int main(int argc, char **argv)
{
    pthread_t tid;

    puts("begin");
    int err = pthread_create(&tid, NULL, func, NULL);
    if(err){
        fprintf(stderr, "pthread_create():%s\n", strerror(err));
        exit(1);
    }
    pthread_join(tid, NULL);
    puts("end");
    return 0;
}
